package edu.co.gap.persistence;

import static com.googlecode.javacv.cpp.opencv_highgui.CV_LOAD_IMAGE_GRAYSCALE;
import static edu.co.gap.util.FileHelper.loadIplImage;
import static edu.co.gap.util.FileHelper.LoadImageInBytes;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.googlecode.javacv.cpp.opencv_core.IplImage;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.Mongo;
import com.mongodb.MongoException;
import com.mongodb.gridfs.GridFS;
import com.mongodb.gridfs.GridFSDBFile;
import com.mongodb.gridfs.GridFSInputFile;

import edu.co.gap.webservices.WebServices;


public class MongoDBHelper {

	//instance of mongo
	Mongo mongo;
	
	//instance of database
	DB database;
	
	//instance GridFS
	GridFS gridFs;

	// :s
	
	public Map<Integer, String> map=new HashMap<Integer, String>();
	
	public MongoDBHelper(String dataBaseName,String namespace) throws UnknownHostException, MongoException {
		mongo = new Mongo();
		database = mongo.getDB( dataBaseName );
		gridFs = new GridFS( database,namespace );
	}
	
	public MongoDBHelper(String dataBaseName,String namespace,String ipHost) throws UnknownHostException, MongoException {
		mongo = new Mongo(ipHost);
		database = mongo.getDB( dataBaseName );
		gridFs = new GridFS( database,namespace );
	}
	
	public MongoDBHelper(String dataBaseName,String namespace,String ipHost,int port) throws UnknownHostException, MongoException {
		mongo = new Mongo(ipHost,port);
		database = mongo.getDB( dataBaseName );
		gridFs = new GridFS( database,namespace );
	}
	
	public void insertIntoCollection(String collection,BasicDBObject info) {
		
		DBCollection coll = database.getCollection(collection);
		
		coll.insert(info);
		

	}
	
	
	public void saveImage( byte[] imageBytes) {
		
//		GridFSInputFile in = gridFs.createFile( imageBytes );
//	    in.save();

	}
	
//	public void saveImage( byte[] imageBytes,long id) {
//		
//		GridFSInputFile in = gridFs.createFile( imageBytes );
//	    in.save(id);
//
//	}
	
	public void saveImage( byte[] imageBytes,String id) {
		
		GridFSInputFile in = gridFs.createFile( imageBytes );
		in.put("id", id);
	    in.save();
	}
public void saveImage( byte[] imageBytes,String id,String filename) {
		
		GridFSInputFile in = gridFs.createFile( imageBytes );
		in.put("id", id);
		in.setFilename(filename);
	    in.save();
	}

public void deleteImage(int filename) {

	gridFs.remove(gridFs.findOne(new BasicDBObject().append("filename", filename)));

}
public void deleteImage(String id) {

	gridFs.remove(gridFs.findOne(new BasicDBObject().append("id", id)));

}
public void deleteAllImage(String id) {
	List<GridFSDBFile> a=gridFs.find(new BasicDBObject().append("id", id));
	while (!a.isEmpty()) {
		gridFs.remove(a.get(0));
		a.remove(0);
	}

}
public void saveImage( byte[] imageBytes,String id,String filename,String contentType) {
	
	GridFSInputFile in = gridFs.createFile( imageBytes );
	in.put("id", id);
	in.setFilename(filename);
	in.setContentType(contentType);
    in.save();
}

	public void storeImage( String filepath,GridFSDBFile out) throws IOException {
		
		FileOutputStream outputImage = new FileOutputStream(filepath);        
	    out.writeTo( outputImage );        
	    outputImage.close();

	}
	
	public GridFSDBFile getImage(String id) {
		
		 GridFSDBFile out = gridFs.findOne( new BasicDBObject( "id" ,id ) );
		 
		 return out;
	}
	
	public void close() {
		mongo.close();
	}
	
//	public List<IplImage>  getAllImagesCollection(String collectionName) throws IOException {
//
//		DBCollection collection = database.getCollection(collectionName);
//		
//		DBCursor cursor=collection.find();
//		
//		List<IplImage> images=new LinkedList<IplImage>();
//		
//		while(cursor.hasNext()) {
//			
//			DBObject dbo=cursor.next();
//			GridFSDBFile out=gridFs.findOne( new BasicDBObject( "_id" ,dbo.get("_id") ) );
//			
//			String fileInputPath="%GAP_STORING%/IMAGES/"
//				.concat("aux").concat(".jpg");
//			
//			 //Save loaded image from database into new image file
//		    FileOutputStream outputImage = new FileOutputStream(fileInputPath);        
//		    out.writeTo( outputImage );        
//		    outputImage.close();
//		    
//		    images.add(loadIplImage(fileInputPath, CV_LOAD_IMAGE_GRAYSCALE));
//		    
//            System.out.println(dbo);
//        }
//	
//		return images;
//	}
	
	public IplImage[]  getAllImagesCollection(String imageFormat) throws IOException {

		File a =new File("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.txt");
//		a.createNewFile();
		System.out.println(a.getAbsolutePath());
		System.out.println(a.getCanonicalPath());
		System.out.println(a.getParentFile());
//		DBCollection collection = database.getCollection(collectionName);
		
		DBCursor cursor=gridFs.getFileList();
		
		IplImage[] images=new IplImage[cursor.count()];
		
		for(int i=0;cursor.hasNext();i++) {
			
			DBObject dbo=cursor.next();
			GridFSDBFile out=gridFs.findOne( new BasicDBObject( "_id" ,dbo.get("_id") ) );
			
//			String fileInputPath=System.getenv("GAP_STORING").concat("/IMAGES/")
//				.concat("aux").concat(".").concat(imageFormat);
			
//			String fileInputPath="/images/".concat("aux").concat(".").concat(imageFormat);
			String imagepath="images/1.pgm";
			 //Save loaded image from database into new image file
			storeImage(imagepath, out);
//		    FileOutputStream outputImage = new FileOutputStream(imagepath);        
//		    out.writeTo( outputImage );        
//		    outputImage.close();
		    images[i]=(loadIplImage(imagepath, CV_LOAD_IMAGE_GRAYSCALE));
		    
		    map.put(i, (String)dbo.get("id"));
		    System.err.println(i+"="+(String)dbo.get("id"));
            System.out.println(dbo);
        }
	
		return images;
	}

	public void printCollections() {
		Set<String> colls = database.getCollectionNames();

		for (String s : colls) {
		    System.out.println(s);
		}
	}
	
	public void printGridFs() {
		DBCursor cursor= gridFs.getFileList();
		
		for(int i=0;cursor.hasNext();i++) {
			
			DBObject dbo=cursor.next();
			GridFSDBFile out=gridFs.findOne( new BasicDBObject( "_id" ,dbo.get("_id") ) );
            System.out.println(dbo);
        }
		
	}
	
	public Object getItem(String collectionname,String id,String field) {
		DBCollection collection = database.getCollection(collectionname);
		BasicDBObject query=new BasicDBObject();
		query.put("id", id);
		return collection.findOne(query).get(field);
	}
	
	public void printCollection(String collectionname) {
	DBCollection collection = database.getCollection(collectionname);
		
		DBCursor cursor=collection.find();
		
		while (cursor.hasNext()) {
			System.out.println(cursor.next());
		}
	}
	public static void main(String[] args) throws Throwable {
		
		MongoDBHelper m=new MongoDBHelper("GAP",WebServices.NAMESPACE_IMAGES_REAL);
		
//		BasicDBObject person=new BasicDBObject();
//		person.put("id", "Raquel");
//		person.put("name", "Raquel chachon");
//		
//		m.insertIntoCollection("PERSON", person);
//		m.deleteImage("David");
//		m.printCollection("MUNDO.files");
//		m.printCollection("PERSON");
//		m.printCollections();
//		m.deleteAllImage("Carolina");
//		m.getAllImagesCollection("pgm");
		
//		String imagepath="images/s4/1.pgm";
//		String imagepath="images/Carolina/1.jpg";
//		m.saveImage(LoadImageInBytes(imagepath), "Carolina", "1");
//		m.saveImage(LoadImageInBytes(imagepath), "s4", "1");
		
//		String imagepath="images/1.pgm";
//		System.out.println(fileExist("images/s1/1.pgm"));;
		
//		m.saveImage(LoadImageInBytes(imagepath), 4);
//		String fileInputPath=System.getenv("GAP_STORING").concat("/IMAGES/")
//		.concat("aux").concat(".").concat("pgm");
//		
//		m.storeImage(fileInputPath, m.getImage("s1"));
		
		
		
	}
}
